package com.next

import grails.converters.JSON
import grails.gorm.transactions.Transactional
import net.sf.jasperreports.engine.JRException
import net.sf.jasperreports.engine.JRExporterParameter
import net.sf.jasperreports.engine.JasperExportManager
import net.sf.jasperreports.engine.JasperFillManager
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import net.sf.jasperreports.engine.export.JRPdfExporter
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter
import nine.jasper.JasperService
import nine.jasper.spring.JasperReportDef
import nine.reports.ReportFormat
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['permitAll'])
class BillsItemController
{
    def springSecurityService
    def componentService
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max)
    {
        params.max = Math.min(max ?: 10, 100)
        respond BillsItem.list(params), model: [billsItemCount: BillsItem.count()]
    }

    def show(BillsItem billsItem)
    {
        respond billsItem
    }

    def create()
    {
        def oid = params.opportunity
        def billsId = params.bills
        def bills = Bills.findById(billsId)
        def opportunity = bills.opportunity
        def credit = OpportunityBankAccount.findByOpportunityAndType(opportunity, OpportunityBankAccountType.findByName("还款账号"))?.bankAccount
        def debit = OpportunityBankAccount.findByOpportunityAndType(opportunity, OpportunityBankAccountType.findByName("收款账号"))?.bankAccount
        respond new BillsItem(params), model: [oid: oid, billsId: billsId, bills: bills, credit: credit, debit: debit]
    }

    @Transactional
    def save(BillsItem billsItem)
    {
        if (billsItem == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (billsItem.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond billsItem.errors, view: 'create'
            return
        }
        def oid = params.oid
        def billsId = params.billsId
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        if (oid && billsId)
        {
            def bills = Bills.findById(billsId)
            def opportunity = bills.opportunity
            def credit = OpportunityBankAccount.findByOpportunityAndType(opportunity, OpportunityBankAccountType.findByName("还款账号"))?.bankAccount
            def debit = OpportunityBankAccount.findByOpportunityAndType(opportunity, OpportunityBankAccountType.findByName("收款账号"))?.bankAccount
            billsItem.bills = bills
            billsItem.credit = credit
            billsItem.debit = debit
            billsItem.createdTime = new Date()
            billsItem.createdBy = user
            //            def startTime
            //            if (billsItem.period == 0) {
            //                startTime = billsItem.startTime + 1
            //            } else {
            //                startTime = billsItem.startTime - 2
            //            }
            //            println "1"
            //            billsItem.transactionRecord = TransactionRecord.findByOpportunityAndPlannedStartTimeAndRepaymentMethod(opportunity,startTime,RepaymentMethod.findByName("富友代扣"))
            //            if(billsItem.transactionRecord){
            //                println billsItem.transactionRecord
            //                billsItem.transactionRecord.amount += billsItem.receivable
            //            }
            billsItem.save flush: true
        }
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'billsItem.label',
                                                                                        default: 'BillsItem'),
                    billsItem.id])
                redirect controller: "opportunity", action: "show", method: "GET", id: oid
            }
            '*' { respond billsItem, [status: CREATED] }
        }
    }

    def edit(BillsItem billsItem)
    {
        def oid = params.opportunity
        if (params?.isJq)
        {
            def isJq = params.isJq
            respond billsItem, model: [oid: oid, isJq: isJq]
        }
        else
        {
            respond billsItem, model: [oid: oid]
        }
    }

    @Transactional
    def update(BillsItem billsItem)
    {
        if (billsItem == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (billsItem.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond billsItem.errors, view: 'edit'
            return
        }
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        billsItem.type = BillsItemType.findById(billsItem?.type?.id)
        billsItem.modifiedBy = user
        billsItem.save flush: true
        def id = params.oid
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'billsItem.label',
                                                                                        default: 'BillsItem'),
                    billsItem.id])
                redirect controller: "opportunity", action: "show", method: "GET", id: id
            }
            '*' { respond billsItem, [status: OK] }
        }
    }

    @Transactional
    def delete(BillsItem billsItem)
    {

        if (billsItem == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        billsItem.delete flush: true
        def id = params.oid
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'billsItem.label',
                                                                                        default: 'BillsItem'),
                    billsItem.id])
                redirect controller: "opportunity", action: "show", method: "GET", id: id
            }
            '*' { render status: NO_CONTENT }
        }
    }

    @Transactional
    def deleteAll()
    {
        def id = params.opportunity
        def opportunity = Opportunity.findById(id)
        def bills = opportunity?.bills[0]
        if (bills == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }
        def items = BillsItem.findAllByBills(bills)
        items.each {
            it.delete flush: true
        }
        redirect controller: "opportunity", action: "show", method: "GET", id: id
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'billsItem.label',
                                                                                          default: 'BillsItem'),
                    params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    /**
     * 修改还款计划状态
     * @author Nagelan
     */
    def updateStatus()
    {
        def billsItem = BillsItem.findById(params["billItemId"])
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        def key = params["name"]
        def value = params["dataName"]
        boolean val
        if (value == "true")
        {
            val = true
        }
        else
        {
            val = false
        }
        def data = [:]
        if (billsItem && key && value)
        {
            billsItem.modifiedBy = user
            if (key == "split")
            {
                billsItem.split = val
            }
            else if (key == "prepayment")
            {
                billsItem.prepayment = val
            }
            else
            {
                billsItem.overdue = val
            }
            if (billsItem.validate())
            {
                billsItem.save()
                data["status"] = "success"
                data["msg"] = "保存成功"
            }
            else
            {
                data["status"] = "failure"
                data["msg"] = "校验失败"
            }
        }
        else
        {
            data["status"] = "failure"
            data["msg"] = "没有取到值"
        }
        render data as JSON
    }

    /**
     * 重置还款计划退回到指定状态
     * @author Nagelan*      */
    @Secured(['permitAll'])
    @Transactional
    def resetBillsItems()
    {
        def result
        def id = params.opportunity
        def opportunity = Opportunity.findById(id)
        def component = Component.findByName("重置还款计划")
        if (component && opportunity)
        {
            result = componentService.evaluate component, opportunity
        }

        if (result instanceof Exception)
        {
            println "SystemComponent error!"
        }

        redirect controller: "opportunity", action: "show", method: "GET", id: opportunity?.id
    }

    /**
     * 手动生成还款计划
     * 判断执行哪种还款计划的生成
     * @author Nagelan* @modified wangchao 2017-7-4
     * */
    @Secured(['permitAll'])
    @Transactional
    def eventEvaluate(Opportunity opportunity)
    {
        def result
        def component
        if (opportunity?.type?.name == "抵押贷款")
        {
            component = Component.findByName("生成还款计划")
        }
        else if (opportunity?.type?.name == "抵押贷款展期")
        {
            component = Component.findByName("展期还款计划")
        }
        else if (opportunity?.type?.name == "抵押贷款结清")
        {
            component = Component.findByName("结清计划")
        }
        else if (opportunity?.type?.name == "抵押贷款早偿")
        {
            component = Component.findByName("早偿还款计划")
        }
        else if (opportunity?.type?.name == "抵押贷款逾期")
        {
            component = Component.findByName("逾期还款计划")
        }
        if (component)
        {
            result = componentService.evaluate component, opportunity
        }

        if (result instanceof Exception)
        {
            println "SystemComponent error!"
        }

        redirect controller: "opportunity", action: "show", method: "GET", id: opportunity?.id
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    def deleteErrorTransactionRecord()
    {
        def startTime = params.startTime
        def endTime = params.endTime
        def opportunities = Opportunity.findAll("from Opportunity where type.name = '抵押贷款' and actualLendingDate between '${startTime}' and '${endTime}' and actualLoanAmount != 0")
        opportunities.each {
            def transactionRecord = TransactionRecord.findAll("from TransactionRecord where opportunity.id = ${it.id} and status.name not in ('待确认','未执行')")
            def transactionRecords = TransactionRecord.findAllByOpportunity(it)
            if (transactionRecord.size() == 0)
            {
                println "删除还款计划opportunity.id = " + it.id
                def billsItem = BillsItem.findAllByBills(Bills.findByOpportunity(it))
                billsItem.each {
                    it.delete()
                }

            }
            if (transactionRecord.size() == 0)
            {
                println "删除交易记录opportunity.id = " + it.id
                transactionRecords.each {
                    it.delete()
                }
            }
        }
        render "success"
    }

    /**
     * 下载还款计划（告知书）
     * @param opportunityId
     * @return map* @author Nagelan
     */
    @Transactional
    def download(Opportunity opportunity)
    {
        def items = []
        def itemsService = []
        def itemsAll = []
        def itemsPlat = []
        def bills = [:]
        opportunity = Opportunity.findById(opportunity?.id)
        if (opportunity?.type != OpportunityType.findByName("抵押贷款"))
        {
            opportunity = opportunity?.parent
        }
        def opportunityBills = opportunity?.bills
        //还本类型
        def principalPaymentType = opportunity?.productAccount?.principalPaymentMethod?.name
        //产品类型
        def productType = opportunity?.product?.name
        def op = OpportunityProduct.findAllByOpportunityAndProduct(opportunity, opportunity?.productAccount)
        if (opportunityBills && op)
        {
            //还款计划的基础信息
            bills["fullName"] = opportunity?.fullName
            def principal = opportunity?.actualLoanAmount ? opportunity?.actualAmountOfCredit : opportunity?.actualLoanAmount
            bills["actualAmountOfCredit"] = principal
            bills["actualLoanDuration"] = opportunity?.actualLoanDuration
            def interestPaymentMethod = opportunity?.interestPaymentMethod?.name
            if (interestPaymentMethod == "上扣息")
            {
                bills["interestPaymentMethod"] = interestPaymentMethod + "(" + (int) opportunity?.monthOfAdvancePaymentOfInterest + "个月)"
            }
            else if (interestPaymentMethod == "下扣息")
            {
                (bills["interestPaymentMethod"] = interestPaymentMethod + "(" + opportunity?.lastPayMonthes + "个月)")
            }
            else
            {
                bills["interestPaymentMethod"] = interestPaymentMethod
            }
            def contract = Contract.executeQuery("select c.serialNumber from OpportunityContract oc left join oc.contract c left join c.type t left join oc.opportunity o where o.id = ${opportunity?.id} and t.name = '借款合同'")
            if (contract)
            {
                bills["serialNumber"] = contract[0]
            }
            def advancePayment = OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, ProductInterestType.findByName("意向金"))?.rate == 0 ? opportunity?.advancePayment : OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, ProductInterestType.findByName("意向金"))?.rate
            bills["advancePayment"] = advancePayment
            def interestRates = OpportunityProduct.findAllByOpportunityAndProductAndContractType(opportunity, opportunity?.productAccount, ContractType.findByName("借款合同"))
            def interestRate = 0
            interestRates.each {
                if (it?.installments)
                {
                    interestRate += it?.rate
                }
                else
                {
                    interestRate += it?.rate / opportunity?.actualLoanDuration
                }
            }
            bills["interestRate"] = interestRate
            bills["actualLendingDate"] = opportunity?.actualLendingDate.format("yyyy-MM-dd")
            //订单结束时间处理
            Calendar calendar = Calendar.getInstance()
            calendar.clear()
            calendar.setTime(opportunity?.actualLendingDate)
            def day = calendar.get(Calendar.DAY_OF_MONTH)
            calendar.add(Calendar.MONTH, opportunity?.actualLoanDuration)
            def monthMaxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
            def endDate = calendar.get(Calendar.DAY_OF_MONTH)
            println monthMaxDays
            if (endDate < day)
            {
                println '此月天数小于初始月份天数'
            }
            else
            {
                println '此月天数不小于初始月份天数'
                calendar.add(Calendar.DAY_OF_MONTH, -1)
            }
            def opportunityEndTime = calendar.getTime().format("yyyy-MM-dd")
            bills["endTime"] = opportunityEndTime
            def serviceTimes = 1
            bills["serviceTimes"] = serviceTimes
            bills["platformCharge"] = OpportunityProduct.findByOpportunityAndProductAndInstallmentsAndProductInterestType(opportunity, opportunity?.productAccount, true, ProductInterestType.findByName("服务费费率"))?.rate
            if (serviceTimes == 2)
            {
                bills["serviceChargeOne"] = OpportunityProduct.findByOpportunityAndProductAndInstallmentsAndProductInterestType(opportunity, opportunity?.productAccount, false, ProductInterestType.findByName("服务费费率"))?.rate / opportunity?.actualLoanDuration
            }
            else
            {
                def serviceCharge = OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, ProductInterestType.findByName("服务费费率"))
                if (serviceCharge)
                {
                    if (serviceCharge?.installments)
                    {
                        bills["serviceChargeOne"] = serviceCharge?.rate
                    }
                    else
                    {
                        bills["serviceChargeOne"] = serviceCharge?.rate / opportunity?.actualLoanDuration
                    }
                }
                else
                {
                    bills["serviceChargeOne"] = 0
                }
            }
            def serviceCharge = OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, ProductInterestType.findByName("渠道返费费率"))
            if (serviceCharge)
            {
                if (serviceCharge?.installments)
                {
                    bills["serviceChargeTwo"] = serviceCharge?.rate
                }
                else
                {
                    bills["serviceChargeTwo"] = serviceCharge?.rate / opportunity?.actualLoanDuration
                }
            }
            else
            {
                bills["serviceChargeTwo"] = 0
            }
            //还款计划详情
            //上扣息月份数
            def dayFirst
            def dayLast
            def firstPayOfMonthes = opportunity?.monthOfAdvancePaymentOfInterest?.intValue() == 0 ? 1 : opportunity?.monthOfAdvancePaymentOfInterest?.intValue()
            //意向金
            if (day < 15)
            {
                if (interestPaymentMethod == "下扣息")
                {
                    firstPayOfMonthes = 1
                }
                dayFirst = 20 - day + (firstPayOfMonthes - 1) * 30
                dayLast = 10 + day
            }
            else if (day >= 15 && day < 20)
            {
                if (interestPaymentMethod == "扣息差" && opportunity.actualLoanDuration != 1)
                {
                    firstPayOfMonthes = 2
                }
                if (interestPaymentMethod == "上扣息" && firstPayOfMonthes == 1 && opportunity.actualLoanDuration != 1)
                {
                    firstPayOfMonthes = 2
                }
                if (interestPaymentMethod == "月息年本")
                {
                    firstPayOfMonthes = 2
                }
                if (interestPaymentMethod == "下扣息")
                {
                    firstPayOfMonthes = 1
                }
                dayFirst = 50 - day + (firstPayOfMonthes - 2) * 30
                dayLast = 10 + day
            }
            else
            {
                if (interestPaymentMethod == "下扣息")
                {
                    firstPayOfMonthes = 1
                }
                dayFirst = 50 - day + (firstPayOfMonthes - 1) * 30
                dayLast = day - 20
            }
            for (
                int i = 0;
                    i <= (opportunity.actualLoanDuration - firstPayOfMonthes + 1);
                    i++)
            {
                def item = [:]
                //总
                def item1 = [:]
                //服务费
                def item2 = [:]
                //利息费
                def item3 = [:]
                //平台费
                def billsItems
                if (i == opportunity?.actualLoanDuration + 1)
                {
                    billsItems = BillsItem.findAllByBillsAndPeriod(opportunity?.bills, i - 1)
                }
                else
                {
                    billsItems = BillsItem.findAllByBillsAndPeriod(opportunity?.bills, i)
                }

                if (billsItems)
                {
                    def totalMoney = 0
                    def serviceMoney = 0
                    def money = 0
                    def money1 = 0
                    def money2 = 0
                    //平台费
                    def serviceMoney1 = 0
                    //特殊产品的服务费（有两个服务费费率）
                    def installmentsService
                    if (serviceTimes == 2)
                    {
                        installmentsService = false
                    }
                    else
                    {
                        installmentsService = OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, ProductInterestType.findByName("服务费费率"))?.installments
                    }
                    billsItems?.each {
                        def contractType = com.next.OpportunityProduct.findByOpportunityAndProductAndProductInterestType(opportunity, opportunity?.productAccount, com.next.ProductInterestType.findByName(it?.type?.name))?.contractType?.name
                        totalMoney += it.receivable
                        if (contractType == "借款合同")
                        {
                            money += it.receivable
                        }
                        else if (contractType == "委托借款代理服务合同")
                        {
                            serviceMoney += it.receivable
                        }
                        if (it?.type?.name == "服务费费率" && serviceTimes == 2)
                        {
                            money2 += it.receivable
                        }
                    }
                    if (serviceTimes == 2)
                    {
                        def serviceRate = OpportunityProduct.findByOpportunityAndProductAndInstallmentsAndProductInterestType(opportunity, opportunity?.productAccount, false, ProductInterestType.findByName("服务费费率"))?.rate
                        if (serviceRate)
                        {
                            serviceMoney1 = principal * serviceRate
                            if (i == 0)
                            {
                                money2 -= serviceMoney1
                            }
                        }
                        else
                        {
                            serviceMoney1 = 0
                        }
                    }
                    //服务费列表
                    item1["installmentsService"] = installmentsService
                    item1["startTime"] = billsItems[0].startTime.format("yyyy-MM-dd")
                    item1["endTime"] = billsItems[0].endTime.format("yyyy-MM-dd")
                    item1["money"] = serviceMoney
                    item1["period"] = i
                    if (i == 0)
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item1["repaymentDate"] = (billsItems[0].startTime + 1)?.format("yyyy-MM-dd")
                        }
                        else
                        {
                            item1["repaymentDate"] = (billsItems[0].startTime + 1)?.format("yyyy-MM-dd")
                        }
                        item1["days"] = dayFirst
                        item1["monthes"] = ""
                        if (!installmentsService)
                        {
                            item1["startTime1"] = billsItems[0].startTime.format("yyyy-MM-dd")
                            item1["endTime1"] = opportunityEndTime
                            item1["monthes1"] = opportunity?.actualLoanDuration
                            if (serviceTimes == 2)
                            {
                                item1["serviceMoney"] = serviceMoney1
                            }
                            else
                            {
                                item1["serviceMoney"] = serviceMoney - money1
                            }
                            item1["money1"] = money1
                        }
                    }
                    else if (i == (opportunity.actualLoanDuration - firstPayOfMonthes + 1))
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item1["repaymentDate"] = opportunityEndTime
                        }
                        else
                        {
                            item1["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item1["days"] = dayLast
                        item1["monthes"] = ""
                    }
                    else
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item1["repaymentDate"] = (billsItems[0].endTime + 1).format("yyyy-MM-dd")
                        }
                        else
                        {
                            item1["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item1["days"] = ""
                        item1["monthes"] = 1
                    }
                    if (serviceMoney != 0)
                    {
                        itemsService.add(item1)
                    }
                    //利息告知书
                    item2["installmentsService"] = installmentsService
                    item2["startTime"] = billsItems[0].startTime.format("yyyy-MM-dd")
                    item2["endTime"] = billsItems[0].endTime.format("yyyy-MM-dd")
                    item2["money"] = money
                    item2["period"] = i
                    if (i == 0)
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item2["repaymentDate"] = (billsItems[0].endTime + 1)?.format("yyyy-MM-dd")
                        }
                        else
                        {
                            item2["repaymentDate"] = (billsItems[0].startTime + 1)?.format("yyyy-MM-dd")
                        }
                        item2["days"] = dayFirst
                        item2["monthes"] = ""
                        if (!installmentsService)
                        {
                            item2["startTime1"] = billsItems[0].startTime.format("yyyy-MM-dd")
                            item2["endTime1"] = opportunityEndTime
                        }
                    }
                    else if (i == (opportunity.actualLoanDuration - firstPayOfMonthes + 1))
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item2["repaymentDate"] = opportunityEndTime
                        }
                        else
                        {
                            item2["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item2["days"] = dayLast
                        item2["monthes"] = ""
                    }
                    else
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item2["repaymentDate"] = (billsItems[0].endTime + 1).format("yyyy-MM-dd")
                        }
                        else
                        {
                            item2["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item2["days"] = ""
                        item2["monthes"] = 1
                    }
                    items.add(item2)
                    //所有还款计划
                    item["installmentsService"] = installmentsService
                    item["startTime"] = billsItems[0].startTime.format("yyyy-MM-dd")
                    item["endTime"] = billsItems[0].endTime.format("yyyy-MM-dd")
                    item["money"] = totalMoney
                    item["period"] = i
                    if (i == 0)
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item["repaymentDate"] = (billsItems[0].endTime + 1)?.format("yyyy-MM-dd")
                        }
                        else
                        {
                            item["repaymentDate"] = (billsItems[0].startTime + 1)?.format("yyyy-MM-dd")
                        }
                        if (opportunity?.interestPaymentMethod?.name == '扣息差' && opportunity?.actualLoanDuration == 1)
                        {
                            item["days"] = ""
                            item["monthes"] = 1
                            item["money"] = totalMoney - principal
                        }
                        else
                        {
                            item["days"] = dayFirst
                            item["monthes"] = ""
                        }
                        if (!installmentsService)
                        {
                            item["repaymentDate1"] = (billsItems[0].startTime + 1)?.format("yyyy-MM-dd")
                            item["startTime1"] = billsItems[0].startTime.format("yyyy-MM-dd")
                            item["endTime1"] = opportunityEndTime
                            item["serviceMoney"] = serviceMoney
                            item["money1"] = totalMoney - serviceMoney
                            item["monthes1"] = opportunity?.actualLoanDuration
                        }
                    }
                    else if (i == (opportunity.actualLoanDuration - firstPayOfMonthes + 1))
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item["repaymentDate"] = opportunityEndTime
                        }
                        else
                        {
                            item["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item["days"] = dayLast
                        item["monthes"] = ""
                        if (productType == "速e贷" || principalPaymentType == "到期还本")
                        {
                            item["money"] = totalMoney - principal
                        }
                    }
                    else
                    {
                        if (principalPaymentType == "等额本息" || productType == "等额本息" || interestPaymentMethod == "下扣息")
                        {
                            item["repaymentDate"] = (billsItems[0].endTime + 1)?.format("yyyy-MM-dd")
                        }
                        else
                        {
                            item["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        }
                        item["days"] = ""
                        item["monthes"] = 1
                    }
                    itemsAll.add(item)

                    //平台费
                    item3["installmentsService"] = installmentsService
                    item3["startTime"] = billsItems[0].startTime.format("yyyy-MM-dd")
                    item3["endTime"] = billsItems[0].endTime.format("yyyy-MM-dd")
                    item3["money"] = money2
                    item3["period"] = i
                    if (i == 0)
                    {
                        item3["repaymentDate"] = (billsItems[0].startTime + 1).format("yyyy-MM-dd")
                        item3["days"] = dayFirst
                        item3["monthes"] = ""
                        if (!installmentsService)
                        {
                            item3["startTime1"] = billsItems[0].startTime.format("yyyy-MM-dd")
                            item3["endTime1"] = opportunityEndTime
                        }
                    }
                    else if (i == (opportunity.actualLoanDuration - firstPayOfMonthes + 1))
                    {
                        item3["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        item3["days"] = dayLast
                        item3["monthes"] = ""
                    }
                    else
                    {
                        item3["repaymentDate"] = billsItems[0].startTime.format("yyyy-MM-dd")
                        item3["days"] = ""
                        item3["monthes"] = 1
                    }
                    itemsPlat.add(item3)
                }
            }
            if (productType == "速e贷" || principalPaymentType == "到期还本")
            {
                def item = [:]
                item["startTime"] = opportunity?.actualLendingDate.format("yyyy-MM-dd")
                item["endTime"] = opportunityEndTime
                item["repaymentDate"] = opportunityEndTime
                item["days"] = ""
                item["monthes"] = opportunity?.actualLoanDuration
                item["money"] = principal
                if (day == 20)
                {
                    item["period"] = opportunity.actualLoanDuration - firstPayOfMonthes + 1
                }
                else
                {
                    item["period"] = opportunity.actualLoanDuration - firstPayOfMonthes + 2
                }

                itemsAll.add(item)
            }
        }
        respond bills, model: [bills: bills, items: items, itemsService: itemsService, itemsAll: itemsAll, itemsPlat: itemsPlat], view: 'billsItemsPrint'
    }

    JasperService jasperService

    def accountPdf()
    {
        def dataList = []
        def accounts = Account.findAll()
        def map
        accounts.each {
            map = [:]
            map.id = it.id
            map.code = it.code
            map.created_date = it.createdDate
            map.active = it.active
            map.name = it.name
            map.type = it.type.name
            dataList.add(map)
        }
        def format = ReportFormat.get(response.format) ?: ReportFormat.HTML
        format = 'PDF'
        def model = [format: format, data: dataList, "ReportTitle": "City List", "title": "list"]
        render(view: "account.jrxml", model: model)
    }

    def jasperForDdf()
    {
        def dataList = []
        def accounts = Account.findAll()
        def map
        accounts.each {
            map = [:]
            map.id = it.id
            map.code = it.code
            map.created_date = it.createdDate
            map.active = it.active
            map.name = it.name
            map.type = it.type.name
            dataList.add(map)
        }
        def opts = new JasperReportDef(name: 'billsItem/account.jrxml', //the name of jrxml or compiled .jasper file
                                       fileFormat: ReportFormat.PDF,
                                       parameters: [param1: "param1", param2: "param2"], //pass whatever parameter needed.
                                       reportData: dataList)
        def view = jasperService.getView(opts.name)
        def model = [:]
        model.putAll(opts.parameters)
        model.format = opts.fileFormat
        if (opts.reportData != null)
        {
            model.data = opts.reportData
        }
        view.setupFormat(model)
        response.setHeader("Content-Disposition", "attachment;filename=first.pdf")
        response.setContentType("application/pdf")
        def out = jasperService.generateReport(opts)
        response.setContentLength(out.size())
        def jasperPrint = view.fillReport(model)
        def exporter = new JRPdfExporter()
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream())
        //response.setCharacterEncoding("UTF-8")
        exporter.exportReport()
        def sos = response.getOutputStream()
        out.writeTo(sos)
        sos.flush()
        out.flush()
        sos.close()
        out.close()
        return null
    }

    def jasperForExcel()
    {
        def dataList = []
        def accounts = Account.findAll()
        def map
        accounts.each {
            map = [:]
            map.id = it.id
            map.code = it.code
            map.created_date = it.createdDate
            map.active = it.active
            map.name = it.name
            map.type = it.type.name
            dataList.add(map)
        }
        def opts = new JasperReportDef(name: 'billsItem/account.jrxml', //the name of jrxml or compiled .jasper file
                                       fileFormat: ReportFormat.XLSX,
                                       parameters: [param1: "param1", param2: "param2"], //pass whatever parameter needed.
                                       reportData: dataList)

        def view = jasperService.getView(opts.name)
        def model = [:]
        model.putAll(opts.parameters)
        model.format = opts.fileFormat
        if (opts.reportData != null)
        {
            model.data = opts.reportData
        }
        view.setupFormat(model)
        def jasperPrint = view.fillReport(model)
        def exporter = new JRXlsxExporter()
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream())
        response.setHeader("Content-Disposition", "attachment;filename=first.xlsx")
        response.setContentType("application/vnd.ms-excel")
        response.setCharacterEncoding("UTF-8")
        exporter.exportReport()
        def out = jasperService.generateReport(opts)
        response.setContentLength(out.size())
        def sos = response.getOutputStream()
        out.writeTo(sos)
        sos.flush()
        out.flush()
        sos.close()
        out.close()
        return null
    }

    /** @Description 导出jasper管理，待完善
     * @Params params* @Return null* @Author Nagelan* @DateTime 2018/9/18 0018 14:52
     */
    def jasperForManager()
    {
        def sourceFileName = servletContext.getRealPath("/") + "jasper/account.jasper"
        def printFile
        def dataList = []
        def accounts = Account.findAll()
        def map
        accounts.each {
            map = [:]
            map.id = it.id
            map.code = it.code
            map.created_date = it.createdDate
            map.active = it.active
            map.name = it.name
            map.type = it.type.name
            dataList.add(map)
        }
        def beanColDataSource = new JRBeanCollectionDataSource(dataList)

        def parameters = [:]
        try
        {
            printFile = JasperFillManager.fillReportToFile(sourceFileName, parameters, beanColDataSource)
            if (printFile != null)
            {

                //1.export to PDF
                JasperExportManager.exportReportToPdfFile(printFile, "D:\\sample_report.pdf")
                //2.export to HTML
                JasperExportManager.exportReportToHtmlFile(printFile, "D:\\sample_report.html")

            }
            render "success"
        }
        catch (JRException e)
        {
            e.printStackTrace()
        }
    }
}
